home *** CD-ROM | disk | FTP | other *** search
- #if __SASC
- #include "snap.h"
- #endif
-
- /* Auto: make
- */
-
- IMPORT BOOL Kick36;
-
- IMPORT struct GfxBase *GfxBase;
-
- IMPORT struct SnapRsrc *SnapRsrc;
- IMPORT struct Image DiskImage;
- IMPORT struct Image ClipImage;
- IMPORT struct Gadget DiskGad;
- IMPORT struct Gadget ClipGad;
- IMPORT struct Gadget VProp, HProp;
- IMPORT struct PropInfo VInfo, HInfo;
- IMPORT struct Image VImage, HImage;
- IMPORT struct NewWindow Nw;
- IMPORT UBYTE *WindowTitle;
-
- IMPORT LONG xl; /* leftmost x position */
- IMPORT LONG xr; /* rightmost x position */
- IMPORT LONG yt; /* topmost y position */
- IMPORT LONG yb; /* bottommost y position */
- IMPORT LONG mx, my; /* Mouse position in pixels */
-
- #define GfxFrame 4L
- IMPORT Point OldFrame[];
- IMPORT Point NewFrame[];
- IMPORT LONG OFType; /* Old frame type: ShortFrame/LongFrame */
- IMPORT UWORD Ptrn;
- IMPORT WORD Pattern[];
-
- IMPORT struct RastPort MyRP;
- IMPORT struct BitMap MyBM;
- IMPORT struct Screen *theScreen;
- struct Layer_Info *LockedLayerInfo;
- IMPORT struct RastPort rp;
-
- IMPORT struct timerequest MyTR;
-
- IMPORT LONGBITS cancelsignal, donesignal, movesignal;
- IMPORT LONGBITS clicksignal, ticksignal, timersignal;
- IMPORT WORD action;
-
- LONG TopBar;
- LONG LeftBar;
- LONG RightBar;
- LONG BottomBar;
- LONG ScreenFontHeight;
- struct TextFont *ScreenFont;
-
- VOID FixHeights()
- {
- struct Screen WBScreen;
-
- OpenWorkBench();
- if (GetScreenData((char *)&WBScreen, (LONG)sizeof(struct Screen), WBENCHSCREEN, NULL)) {
- /* Now this is a good practice */
- TopBar = WBScreen.WBorTop + WBScreen.RastPort.TxHeight + 1;
- LeftBar = WBScreen.WBorLeft;
- RightBar = WBScreen.WBorRight;
- BottomBar = WBScreen.WBorBottom;
- ScreenFont = WBScreen.RastPort.Font;
- if (!ScreenFont) {
- Forbid();
- ScreenFont = GfxBase->DefaultFont;
- Permit();
- }
- ScreenFontHeight = ScreenFont->tf_YSize;
- } else {
- /* Sorry, but I don't realise how this could fail.
- Well, if we're snapping on another screen and
- WB is closed and it can't be opened by GetScreenData()...
- Anyway, IF this should happen -- Use Topaz 8 */
- TopBar = 10;
- LeftBar = 2;
- RightBar = 2;
- BottomBar = 1;
- ScreenFontHeight = 8;
- Forbid();
- ScreenFont = GfxBase->DefaultFont;
- Permit();
- }
- }
-
- /* SnapGfx is the actual graphics snapper.
- ** It steals the bitmap data from the given rastport
- ** and puts it in a separate bitmap.
- ** It also prepares the NewWindow structure according
- ** to the snapped bitmap.
- ** The coordinates are assumed to be valid.
- */
-
- struct GfxSnap *SnapGfx(rp)
- struct RastPort *rp;
- {
- struct GfxSnap *GS;
- LONG i;
-
- GS = Create(GfxSnap);
- if (!GS) {
- return NULL;
- }
-
- GS->x = xl;
- GS->y = yt;
- GS->width = xr - xl + 1;
- GS->height = yb - yt + 1;
- if (xr < xl + MINWIDTH) { /* Can't have too small windows */
- xr = xl + MINWIDTH;
- }
- if (yb < yt + MINHEIGHT) {
- yb = yt + MINHEIGHT;
- }
- GS->depth = rp->BitMap->Depth;
- GS->viewmode = theScreen->ViewPort.Modes;
- GS->pagew = theScreen->Width;
- GS->pageh = theScreen->Height;
- i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
- /* Copy the color map in case we should need it later */
- while (i--) {
- ULONG col = GetRGB4(theScreen->ViewPort.ColorMap, i);
- GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
- GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
- GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
- }
- /* Set up a nice bitmap */
- InitBitMap(&GS->BM, GS->depth, GS->width, GS->height);
- /* Get a handle on the bitmap */
- InitRastPort(&MyRP);
- MyRP.BitMap = &GS->BM;
- if (!AllocPlanes(&GS->BM, GS->width, GS->height)) {
- FreePlanes(&GS->BM, GS->width, GS->height);
- Kill(GS);
- return NULL;
- }
- /* Copy the selected part of the screen */
- ClipBlit(rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
- if (!Kick36) {
- VInfo.Flags |= PROPBORDERLESS;
- HInfo.Flags |= PROPBORDERLESS;
- }
- CopyMem((char *)&DiskGad, (char *)&GS->DiskGad,
- (LONG)sizeof(DiskGad) + sizeof(ClipGad) + sizeof(VProp) + sizeof(HProp) +
- sizeof(VInfo) + sizeof(HInfo) + sizeof(VImage) + sizeof(HImage));
- GS->topbar = TopBar;
- GS->leftbar = LeftBar;
- GS->rightbar = 18; /* (Kick36 ? RightBar : 18); */
- GS->bottombar = 10;
-
- Nw.LeftEdge = xl;
- Nw.TopEdge = yt;
- Nw.Width = xr - xl + 1 + GS->leftbar + GS->rightbar;
- Nw.Height = yb - yt + 1 + GS->topbar + GS->bottombar;
- Nw.Flags &= ~(SIMPLE_REFRESH | SMART_REFRESH | NOCAREREFRESH);
- Nw.Flags |= (SnapRsrc->flags & SIMPLEREFRESH ?
- SIMPLE_REFRESH : SMART_REFRESH | NOCAREREFRESH);
-
- Nw.Title = WindowTitle;
- Nw.MinWidth = MINWIDTH + 1 + GS->leftbar + GS->rightbar;
- Nw.MinHeight = MINHEIGHT + 1 + GS->topbar + GS->bottombar;
- Nw.MaxWidth = Nw.Width;
- Nw.MaxHeight = Nw.Height;
-
- if (Kick36) Nw.Flags |= SIZEBBOTTOM|SIZEBRIGHT;
-
- return GS;
- }
-
- VOID ExtendGfx()
- {
- /* Fix which row we're talking about */
- if (my - yt < yb - my) { /* Find closest row */
- yt = my; /* change top row */
- } else {
- yb = my; /* change bottom row */
- }
- if (mx - xl < xr - mx) {
- xl = mx;
- } else {
- xr = mx;
- }
- }
-
- VOID gfx_frame()
- {
- NewFrame[0].x = xl; NewFrame[0].y = yt;
- NewFrame[1].x = xr; NewFrame[1].y = yt;
- NewFrame[2].x = xr; NewFrame[2].y = yb;
- NewFrame[3].x = xl; NewFrame[3].y = yb;
- NewFrame[4].x = xl; NewFrame[4].y = yt;
- draw_frame(GfxFrame);
- }
-
- WORD HandleGfx()
- {
- theScreen = WhichScreen(); /* Find out where we are */
- if (!theScreen) { /* Don't know? Forget it. */
- action = noaction;
- return 0;
- }
- /* Lock everything - find out what happens */
- LockedLayerInfo = &theScreen->LayerInfo;
- LockLayers(LockedLayerInfo);
-
- /* Get a copy. Don't mess with somebody else's RP. */
- CopyMem((char *)&theScreen->RastPort, (char *)&rp, (long)sizeof(struct RastPort));
- SetDrMd(&rp, COMPLEMENT);
-
- xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
- if (xl < 0) {
- xl = 0;
- }
- if (xl >= theScreen->Width) { /* Check those corners. Check those corners. */
- xl = theScreen->Width - 1;
- }
- yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
- if (yt < 0) {
- yt = 0;
- }
- if (yt >= theScreen->Height) {
- yt = theScreen->Height - 1;
- }
- xr = xl;
- yb = yt;
- Ptrn = (SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[UNIT_FRAME]);
- OFType = 0L;
- gfx_frame();
-
- FOREVER {
- REGISTER LONGBITS sig;
-
- MyTR.tr_time.tv_secs = 0;
- MyTR.tr_time.tv_micro = 500000;
- MyTR.tr_node.io_Command = TR_ADDREQUEST;
- SendIO((struct IORequest *)&MyTR);
-
- sig = Wait(movesignal | clicksignal | cancelsignal |
- donesignal | ticksignal | timersignal);
-
- if (CheckIO((struct IORequest *)&MyTR)) {
- WaitIO((struct IORequest *)&MyTR);
- erase_frame();
- UnlockLayers(LockedLayerInfo); /* Unlock things */
- sig = Wait(ticksignal); /* Wait for input handler to become avtive */
- LockLayers(LockedLayerInfo); /* Re-lock */
- /* I guess I should check to see that the window is still
- there. Aw, what the heck. Apologies to anyone who gets
- bitten by this. */
- DisplayBeep(NULL);
- gfx_frame();
- } else {
- AbortIO((struct IORequest *)&MyTR);
- WaitIO((struct IORequest *)&MyTR);
- SetSignal(0, timersignal);
- }
-
- if ((sig & ticksignal) && (SnapRsrc->CrawlPtrn != 0xffff)) {
- crawl_frame(1L);
- }
-
- if (sig & movesignal || sig & clicksignal) {
- mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
- if (mx < 0) {
- mx = 0;
- }
- if (mx>=theScreen->Width) {
- mx = theScreen->Width - 1;
- }
- my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
- if (my < 0) {
- my = 0;
- }
- if (my>=theScreen->Height) {
- my = theScreen->Height - 1;
- }
- ExtendGfx();
- gfx_frame();
- }
- if (sig & cancelsignal) { /* Cancelled? */
- erase_frame();
- UnlockLayers(LockedLayerInfo);
- return 0;
- }
- if (sig & donesignal) { /* Finished. Copy gfx. */
- struct GfxSnap *GS;
-
- erase_frame();
- if (xl == xr || yt == yb) {
- action = noaction;
- UnlockLayers(LockedLayerInfo);
- return 0;
- }
- if (xr >= theScreen->Width) {
- xl -= xr - theScreen->Width - 1;
- xr = theScreen->Width - 1;
- }
- if (yb >= theScreen->Height) {
- yt -= yb - theScreen->Height - 1;
- yb = theScreen->Height - 1;
- }
- FixHeights();
- GS = SnapGfx(&rp); /* Snap! */
- UnlockLayers(LockedLayerInfo);
- if (GS) {
- if (GS->window = opensharedwindow(&Nw)) {
- if (SnapRsrc->flags & SIMPLEREFRESH) {
- ModifyIDCMP(GS->window,
- GS->window->IDCMPFlags | REFRESHWINDOW);
- }
- if (Kick36) {
- GS->topbar = GS->window->BorderTop;
- GS->leftbar = GS->window->BorderLeft;
- GS->rightbar = GS->window->BorderRight;
- GS->bottombar = 10;/*GS->window->BorderBottom;*/
-
- GS->HProp.TopEdge = -7;
- GS->HProp.Height = 6;
- }
-
- GS->DiskGad.TopEdge = GS->topbar;
- GS->DiskGad.LeftEdge = (Kick36 ? -17 : -14);
- GS->DiskGad.Width = (Kick36 ? 18 : 14);
- GS->ClipGad.TopEdge = GS->DiskGad.TopEdge + 12;
- GS->ClipGad.LeftEdge = (Kick36 ? -17 : -14);
- GS->ClipGad.Width = (Kick36 ? 18 : 14);
- GS->HProp.GadgetRender = (APTR)&GS->HImage;
- GS->HProp.SpecialInfo = (APTR)&GS->HInfo;
- GS->VProp.TopEdge =
- GS->ClipGad.TopEdge + (Kick36 ? 14 : 15);
- GS->VProp.LeftEdge = (Kick36 ? 5 : 7) - GS->rightbar;
- GS->VProp.Width = GS->rightbar - (Kick36 ? 8 : 10);
- GS->VProp.Height =
- (Kick36 ? -28 : -27) - GS->bottombar - GS->topbar;
- GS->VProp.GadgetRender = (APTR)&GS->VImage;
- GS->VProp.SpecialInfo = (APTR)&GS->VInfo;
-
- GS->DiskGad.NextGadget = &GS->ClipGad;
- GS->ClipGad.NextGadget = &GS->VProp;
- GS->VProp.NextGadget = &GS->HProp;
- GS->HProp.NextGadget = NULL;
-
- AddGList(GS->window, &GS->DiskGad, -1, -1, NULL);
- GS->window->UserData = (BYTE *)GS;
- /* Put gfx in our new window */
- AdjustSize(GS);
- } else {
- FreePlanes(&GS->BM, GS->width, GS->height);
- Kill(GS);
- }
- } else { /* Good question */
- }
- action = noaction;
- return 0;
- }
- }
- }
-